package com.peng.utils;

import com.fasterxml.jackson.annotation.JsonCreator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * TailNumber
 *
 * @author: lupeng10
 * @create: 2023-04-20 16:23
 */
public class TailNumber {

    /**
     * 校验格式的正则表达式
     */
    private static final Pattern PATTERN = Pattern.compile("^[0-9;,-]{1,}$");

    /**
     * 默认的除数
     */
    private static final int DEFAULT_DIVISOR = 100;

    private int divisor;
    private int start;
    private int end;
    private Set<Long> whiteSet;
    private Set<Long> blackSet;

    private TailNumber() {
    }

    /***
     * 根据字符串构建TailNumber实例
     * 100;0-99;12345,123123;3456456,3452345
     * 取模的除数，余数的范围，白名单，黑名单
     * 黑白名单多个用户使用英文逗号分隔
     *
     * @param tailNumberDesc TailNumber描述字符串 100;00-99;12345;3456456
     * @return
     */
    @JsonCreator
    public static TailNumber from(String tailNumberDesc) {
        if (!TailNumber.PATTERN.matcher(tailNumberDesc).find()) {
            throw new IllegalArgumentException("tailNumberDesc error: " + tailNumberDesc);
        }
        TailNumber tailNumber = new TailNumber();

        String[] partArr = tailNumberDesc.split(";");

        // parse divisor
        int parseIndex = 0;
        if (!partArr[0].contains("-")) {
            if (partArr.length < 2) {
                throw new IllegalArgumentException("tailNumberDesc error: " + tailNumberDesc);
            }
            parseIndex++;
            tailNumber.divisor = Integer.parseInt(partArr[0]);
        } else {
            tailNumber.divisor = DEFAULT_DIVISOR;
        }

        // parse range
        String rangeDesc = partArr[parseIndex];
        tailNumber.start = Integer.parseInt(rangeDesc.split("-")[0]);
        tailNumber.end = Integer.parseInt(rangeDesc.split("-")[1]);
        parseIndex++;

        // parse whiteSet
        if (partArr.length > parseIndex && StringUtils.isNotBlank(partArr[parseIndex])) {
            tailNumber.whiteSet = Arrays.stream(partArr[parseIndex].split(","))
                    .map(Long::parseLong)
                    .collect(Collectors.toSet());
            parseIndex++;
        }

        // parse blackSet
        if (partArr.length > parseIndex && StringUtils.isNotBlank(partArr[parseIndex])) {
            tailNumber.blackSet = Arrays.stream(partArr[parseIndex].split(","))
                    .map(Long::parseLong)
                    .collect(Collectors.toSet());
        }

        return tailNumber;
    }

    public boolean isOneOf(long userId) {
        if (CollectionUtils.isNotEmpty(blackSet) && blackSet.contains(userId)) {
            return false;
        }
        if (CollectionUtils.isNotEmpty(whiteSet) && whiteSet.contains(userId)) {
            return true;
        }
        long remainder = userId % divisor;
        return start <= remainder && remainder <= end;
    }

}
